﻿#include "customtableview.h"
#include <QDrag>
#include <QMimeData>
#include "globalobject.h"

/********************icondelegate********************/
icondelegate::icondelegate(QObject * parent)
    : QStyledItemDelegate(parent)
{
    m_framecolor = QColor(216, 216, 216);
    m_checkpixmap = QPixmap(":/tableview/resources/skin/tableview/checked.bmp");
    m_uncheckpixmap = QPixmap(":/tableview/resources/skin/tableview/unchecked.bmp");
    m_selectedlist.clear();
}

void icondelegate::setSelectIndexList(QModelIndexList selectedlist)
{
    m_selectedlist.clear();
    m_selectedlist = selectedlist;
}

void icondelegate::clearSelectIndexList()
{
    m_selectedlist.clear();
}

QModelIndexList icondelegate::getSelectIndexList()
{
    return m_selectedlist;
}

void icondelegate::paint(QPainter * painter,
                         const QStyleOptionViewItem & option,
                         const QModelIndex & index) const
{
    QStyledItemDelegate::paint(painter, option, index);

    //绘制表格左边框线
    painter->save();
    QPen pen;
    pen.setColor(m_framecolor);
    pen.setWidth(1);
    pen.setStyle(Qt::SolidLine);
    painter->setPen(pen);
    painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
    painter->restore();

    QPixmap pixmap;
    for(int i = 0; i < m_selectedlist.size(); i++)
    {
        if(m_selectedlist.at(i).row() == index.row())
        {
            pixmap = m_checkpixmap;
            break;
        }
    }
    if(pixmap.isNull())
        pixmap = m_uncheckpixmap;
    int height = pixmap.height();
    QRect rect = option.rect;
    int x = rect.x() + 3;
    int y = rect.y() + rect.height() / 2 - height / 2;
    painter->drawPixmap(x, y, pixmap);

    QString str_index = QString::number(index.row() + 1);
    QFont font = QFont(u8"微软雅黑", 8, QFont::Normal);
    QFontMetrics metric(font);
    painter->setFont(font);
    int xtextspace = x + pixmap.width() + 3;
    int iwidth = (xtextspace + metric.width(str_index) + 5) > option.rect.width() ?
                 (option.rect.width() - xtextspace) : metric.width(str_index) + 5;
    QRect textrect(xtextspace, rect.y() + (rect.height() - metric.height()) / 2, iwidth, 20);
    painter->drawText(textrect, str_index);
}

/********************pixmapdelegate********************/
pixmapdelegate::pixmapdelegate(QObject * parent)
    : QStyledItemDelegate(parent)
{
    m_yespixmap = QPixmap(":/tableview/resources/skin/tableview/yes.png");
    m_nopixmap = QPixmap(":/tableview/resources/skin/tableview/no.png");
    m_pixmaptypelist.clear();
}

pixmapdelegate::~pixmapdelegate()
{
    m_pixmaptypelist.clear();
}

void pixmapdelegate::paint(QPainter * painter,
                           const QStyleOptionViewItem & option,
                           const QModelIndex & index) const
{
    QStyledItemDelegate::paint(painter, option, index);
    QPixmap pixmap = m_pixmaptypelist.at(index.row()) == 1 ? m_yespixmap : m_nopixmap;
    int height = pixmap.height();
    QRect rect = option.rect;
    int x = rect.x();
    int y = rect.y() + rect.height() / 2 - height / 2;
    painter->drawPixmap(x, y, pixmap);
}

bool pixmapdelegate::editorEvent(QEvent * event,
                                 QAbstractItemModel * model,
                                 const QStyleOptionViewItem & /*option*/,
                                 const QModelIndex & index)
{
    return false;
}

void pixmapdelegate::setpixmaptypelist(QList<int> showtypelist)
{
    m_pixmaptypelist = showtypelist;
}

/********************progressbardelegate********************/
progressbardelegate::progressbardelegate(QObject * parent)
    : QStyledItemDelegate(parent)
{
    m_paintbar.setObjectName("delegatebar");
    //进度条样式在tableview初始化函数里设置
//    qApp->setStyleSheet("QProgressBar#delegatebar{border:1px solid grey;text-align: center;background: white;}"
//                          "QProgressBar::chunk#delegatebar{border: none;background: rgb(100, 180, 240);}");
}

progressbardelegate::~progressbardelegate()
{
}

void progressbardelegate::paint(QPainter * painter,
                                const QStyleOptionViewItem & option,
                                const QModelIndex & index) const
{
    QStyleOptionViewItem viewOption(option);
    initStyleOption(&viewOption, index);
    if (option.state.testFlag(QStyle::State_HasFocus))
        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;

    QStyledItemDelegate::paint(painter, viewOption, index);

    int progressvalue = index.model()->data(index, Qt::DisplayRole).toInt();
    int left = 3;
    int top = 4;
    int width = option.rect.width() - 2 * left;
    int height = option.rect.height() - 2 * top;
    // 设置进度条的风格
    QStyleOptionProgressBar progressBarOption;
    progressBarOption.initFrom(option.widget);
    progressBarOption.rect = QRect(option.rect.left() + left, option.rect.top() + top,  width, height);
    progressBarOption.minimum = 0;
    progressBarOption.maximum = 100;
    progressBarOption.textAlignment = Qt::AlignCenter;
    progressBarOption.progress = progressvalue;
    progressBarOption.text = QString("%1%").arg(progressvalue);
    progressBarOption.textVisible = true;
    //绘制进度条
    QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter, &m_paintbar);
}

bool progressbardelegate::editorEvent(QEvent * event,
                                      QAbstractItemModel * model,
                                      const QStyleOptionViewItem & /*option*/,
                                      const QModelIndex & index)
{
    return false;
}

/********************pushbuttondelegate********************/
pushbuttondelegate::pushbuttondelegate(QObject * parent, QString itemtext)
    : QStyledItemDelegate(parent)
{
    m_btntextcolor = QColor(0, 120, 230);
    m_bmousepressed = false;
    m_itemtext = itemtext;
    m_btnrectmap.clear();
    m_currentrect = QRect(0, 0, 0, 0);
    m_paintbtn.setObjectName("delegatebtn");
    //按钮样式在tableview初始化函数里设置
//    qApp->setStyleSheet(QString("QPushButton#delegatebtn{color:rgb(%1, %2, %3);"
//    "text-decoration:underline;background:transparent;}").arg(m_btntextcolor.red())
//                        .arg(m_btntextcolor.green()).arg(m_btntextcolor.blue()));
}

pushbuttondelegate::~pushbuttondelegate()
{
    m_btnrectmap.clear();
}

void pushbuttondelegate::paint(QPainter * painter,
                               const QStyleOptionViewItem & option,
                               const QModelIndex & index) const
{
    //这里有2种方式：1、若初始化传入内容，则绘制内容；2、若初始化没有传入内容，则从Model()里获取内容
    QString itemtext;
    QStyleOptionViewItem viewoption(option);
    if(m_itemtext.isEmpty())
    {
        //设置单元格字体风格
        viewoption.palette.setColor(QPalette::Text, m_btntextcolor);
        viewoption.palette.setColor(QPalette::HighlightedText, m_btntextcolor);
        viewoption.font.setUnderline(true);
        //获取单元格内容
        const QAbstractItemModel *itemmodel = index.model();
        QModelIndex itemindex = itemmodel->index(index.row(), index.column(), QModelIndex());
        itemtext = itemmodel->data(itemindex, Qt::DisplayRole).toString();
    }
    else
    {
        itemtext = m_itemtext;
    }
    QStyledItemDelegate::paint(painter, viewoption, index);
    if(itemtext.isEmpty())
        return;

    //设置按钮风格
    QStyleOptionButton btnopt;
    QFont font = QFont(u8"微软雅黑", 8, QFont::Normal);
    QFontMetrics metric(font);
    int btnwidth = (metric.width(itemtext) + 3) > option.rect.width() ? option.rect.width() : (metric.width(itemtext) + 3);
    QRect btnrect = QRect(option.rect.x() + 3, option.rect.y() + (option.rect.height() - metric.height()) / 2, btnwidth, metric.height());
    btnopt.rect = btnrect;
    btnopt.state |= QStyle::State_Enabled;
    btnopt.fontMetrics = metric;
    if(m_itemtext.isEmpty())
        btnopt.text = "";
    else
        btnopt.text = m_itemtext;
    //保存按钮绘制的位置
    (const_cast<pushbuttondelegate*>(this))->m_btnrectmap.insert(index, btnrect);
    //绘制按钮
    QApplication::style()->drawControl(QStyle::CE_PushButton, &btnopt, painter, &m_paintbtn);
}

bool pushbuttondelegate::editorEvent(QEvent * event,
                                     QAbstractItemModel * model,
                                     const QStyleOptionViewItem & /*option*/,
                                     const QModelIndex & index)
{
    QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
    // 还原鼠标样式
    QApplication::restoreOverrideCursor();

    switch (event->type())
    {
    case QEvent::MouseMove:
    {
        if(index.isValid())
        {
            QRect movetrect = m_btnrectmap.value(index);
            if(movetrect.contains(mouse_event->pos()))
            {
                QApplication::setOverrideCursor(Qt::PointingHandCursor);
            }
        }
        break;
    }
    case QEvent::MouseButtonPress:
    {
        if(mouse_event->button() == Qt::LeftButton)
        {
            m_currentrect = m_btnrectmap.value(index);
            if(m_currentrect.contains(mouse_event->pos()))
            {
                m_bmousepressed = true;
                QApplication::setOverrideCursor(Qt::PointingHandCursor);
            }
        }
        break;
    }
    case QEvent::MouseButtonRelease:
    {
        if(mouse_event->button() == Qt::LeftButton && m_bmousepressed)
        {
            QRect releaserect = m_btnrectmap.value(index);
            if(releaserect == m_currentrect && releaserect.contains(mouse_event->pos()))
            {
                emit btnClicked(index.row(), index.column());
            }
            m_bmousepressed = false;
            m_currentrect = QRect(0, 0, 0, 0);
        }
        break;
    }
    default:
        break;
    }
    return false;
}

/********************customheaderview********************/
customheaderview::customheaderview(Qt::Orientation orientation, QWidget * parent)
    : QHeaderView(orientation, parent)
{
    m_bgcolor = QColor(241, 245, 246);
    m_framecolor = QColor(216, 216, 216);
    m_ischeckall = false;
    m_sortby = 1;
    m_currentcolumn = -1;
    m_checkpixmap.load(":/tableview/resources/skin/tableview/checked.bmp");
    m_uncheckpixmap.load(":/tableview/resources/skin/tableview/unchecked.bmp");
    m_sortwaitpixmap.load(":/tableview/resources/skin/tableview/sort_wait_api.bmp");
    m_sortascpixmap.load(":/tableview/resources/skin/tableview/sort_asc_api.bmp");
    m_sortdescpixmap.load(":/tableview/resources/skin/tableview/sort_desc_api.bmp");
    //设置表头背景色
    setStyleSheet(QString("QHeaderView::section{background-image:url(:/tableview/resources/skin/tableview/head_api.bmp);"
                          "background-color:transparent;padding-left: 3px;border: 1px solid rgb(%1,%2,%3);"
                          "border-right-color:rgb(%4,%5,%6)}").arg(m_bgcolor.red()).arg(m_bgcolor.green()).arg(m_bgcolor.blue())
                  .arg(m_framecolor.red()).arg(m_framecolor.green()).arg(m_framecolor.blue()));
    //设置表头高度
    setFixedHeight(30);
    //设置表头字体
    QFont headeritemfont = QFont(u8"微软雅黑", 9, QFont::Normal);
    setFont(headeritemfont);
    //设置充满表宽度
    setStretchLastSection(true);
    //设置点击表头响应
    setSectionsClickable(true);
    setHighlightSections(false); //点击表时不对表头行光亮（获取焦点）
    connect(this, SIGNAL(sectionClicked(int)), this, SLOT(headerItemClicked(int)));
}

void customheaderview::headerItemClicked(int logicalIndex)
{
    if(logicalIndex == 0)
    {
        m_ischeckall == true ? m_ischeckall = false : m_ischeckall = true;
        m_ischeckall == true ? setCheckAll() : setUncheckAll();
    }
    else
    {
        if(logicalIndex == m_currentcolumn)
        {
            switch (m_sortby)
            {
            case 1:
                m_sortby++;
                break;
            case 2:
                m_sortby++;
                break;
            case 3:
                m_sortby--;
                break;
            default:
                break;
            }
        }
        else
        {
            m_sortby = 3;
            m_currentcolumn = logicalIndex;
        }
        emit headerSortClicked(m_sortby, m_currentcolumn);
    }
}

void customheaderview::paintEvent(QPaintEvent *event)
{
    QHeaderView::paintEvent(event);
}

void customheaderview::mousePressEvent ( QMouseEvent * event )
{
    QHeaderView::mousePressEvent(event);
}

void customheaderview::mouseMoveEvent(QMouseEvent * event)
{
    // 还原鼠标样式
    QApplication::restoreOverrideCursor();
    QHeaderView::mouseMoveEvent(event);
}

void customheaderview::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();
    if (logicalIndex == 0)
    {
        //绘制表头左边框线
        painter->save();
        QPen pen;
        pen.setColor(m_framecolor);
        pen.setWidth(1);
        pen.setStyle(Qt::SolidLine);
        painter->setPen(pen);
        painter->drawLine(getSectionRect(logicalIndex).topLeft(), getSectionRect(logicalIndex).bottomLeft());
        painter->restore();
        m_ischeckall == true ? drawIcon(painter, logicalIndex, m_checkpixmap) : drawIcon(painter, logicalIndex, m_uncheckpixmap);
    }
    else
    {
        drawsorticon(painter, logicalIndex);
    }
}

QRect customheaderview::getSectionRect(int logicalIndex) const
{
    return QRect(sectionViewportPosition(logicalIndex), 0, sectionSize(logicalIndex), height());
}

QRect customheaderview::getIconRect(int logicalIndex) const
{
    QRect sr = getSectionRect(logicalIndex);
    return QRect(sr.left() + 3, sr.center().y() - 6, 14, 14);
}

QRect customheaderview::getSortIconRect(int logicalIndex) const
{
    QRect sr = getSectionRect(logicalIndex);
    return QRect(sr.right() - 15, sr.center().y() - 14, 13, 28);
}

void customheaderview::drawIcon(QPainter *painter, int logicalIndex, QPixmap pixmap) const
{
    painter->save();
    QRect brect = getIconRect(logicalIndex);
    painter->drawPixmap(brect, pixmap);
    QFont font = QFont(u8"微软雅黑", 9, QFont::Normal);
    painter->setFont(font);
    QFontMetrics metric(font);
    QString strtext = "序号";
    QRect textrect(getSectionRect(logicalIndex).x() + 23, (getSectionRect(logicalIndex).height() - metric.height()) / 2, metric.width(strtext) + 5, metric.height());
    painter->drawText(textrect, strtext);
    painter->restore();
}

void customheaderview::drawsorticon(QPainter *painter, int logicalIndex) const
{
    QRect brect = getSortIconRect(logicalIndex);
    if(logicalIndex == m_currentcolumn)
    {
        switch (m_sortby)
        {
        case 1:
            painter->drawPixmap(brect, m_sortwaitpixmap);
            break;
        case 2:
            painter->drawPixmap(brect, m_sortascpixmap);
            break;
        case 3:
            painter->drawPixmap(brect, m_sortdescpixmap);
            break;
        default:
            break;
        }
    }
    else
    {
        painter->drawPixmap(brect, m_sortwaitpixmap);
    }
}

void customheaderview::setCheckAll()
{
    emit headerSelectAll();
    isCheckAll(true);
}

void customheaderview::setUncheckAll()
{
    emit headerClearSelection();
    isCheckAll(false);
}

void customheaderview::isCheckAll(bool ischeckall)
{
    ischeckall == true ? m_ischeckall = true : m_ischeckall = false;
    QRect brect = getIconRect(0);
    update(brect);
}

/********************dragheaderview********************/
dragheaderview::dragheaderview(Qt::Orientation orientation, dragtableview * parent)
    : customheaderview(orientation, parent)
{
    m_parent = parent;
    m_mouselbtnpressed = false;

    m_toplabel = new QLabel(gmainwid);
    m_toplabel->setFixedSize(10, 10);
    m_toplabel->setPixmap(QPixmap(":/tableview/resources/skin/tableview/topcursor.png").scaled(QSize(10, 10)));
    m_toplabel->hide();

    m_bottomlabel = new QLabel(gmainwid);
    m_bottomlabel->setFixedSize(10, 10);
    m_bottomlabel->setPixmap(QPixmap(":/tableview/resources/skin/tableview/bottomcursor.png").scaled(QSize(10, 10)));
    m_bottomlabel->hide();

    m_headerheight = 30;
    m_columnfrom = 0;
    m_columnto = 0;

    this->setAcceptDrops(true);
}

dragheaderview::~dragheaderview(void)
{

}

void dragheaderview::mousePressEvent ( QMouseEvent * event )
{
    if (event->button() == Qt::LeftButton)
    {
        QModelIndex index = m_parent->indexAt(event->pos());
        QRect currentrect = getSectionRect(index.column());
        //当鼠标在各列分割线上时，不拖动
        if (index.isValid() && index.column() > 0 && event->pos().x() > currentrect.left() + 5
                && event->pos().x() < currentrect.right() - 5)
        {
            //qDebug()<< index.row() << index.column();
            m_columnfrom = index.column();
            m_mouselbtnpressed = true;
            m_dragpoint = event->pos();
            m_dragtext = m_parent->model()->headerData(index.column(), Qt::Horizontal, Qt::DisplayRole).toString();
        }
    }
    customheaderview::mousePressEvent(event);
}

void dragheaderview::mouseMoveEvent(QMouseEvent * event)
{
    if (!m_mouselbtnpressed)
    {
        customheaderview::mouseMoveEvent(event);
        return;
    }
    //通过鼠标移动的距离来判断是否启动拖放
    if ((event->pos() - m_dragpoint).manhattanLength()  < QApplication::startDragDistance())
        return;
    startDrag();           //开始拖拽，完成拖拽后才会继续往下走
    m_toplabel->hide();
    m_bottomlabel->hide();
    m_columnto = -1;
    m_mouselbtnpressed = false;
    customheaderview::mouseMoveEvent(event);
}

QColor dragheaderview::changeColorDepth(QColor color, int value)
{
    int red = color.red() + value;
    int green = color.green() + value;
    int blue = color.blue() + value;
    if(red > 255)
        red = 255;
    if(green > 255)
        green = 255;
    if(blue > 255)
        blue = 255;
    if(red < 0)
        red = 0;
    if(green < 0)
        green = 0;
    if(blue < 0)
        blue = 0;
    return QColor(red, green, blue, 200);
}

void dragheaderview::startDrag()
{
    QDrag *drag = new QDrag(this);
    QMimeData *mimeData = new QMimeData;
    QByteArray arytext;
    arytext.append(m_dragtext);
    mimeData->setData("gradheaderitem", arytext);
    drag->setMimeData(mimeData);

    //设置拖拽图片
    int columnwidth = m_parent->columnWidth(m_columnfrom);
    QPixmap dragpix(columnwidth, m_headerheight);
    dragpix.fill(changeColorDepth(m_bgcolor, -30));
    QPainter painter(&dragpix);
    painter.setPen(QColor(0, 0, 0, 200));
    painter.setFont(QFont(u8"微软雅黑", 9, QFont::Normal));
    painter.drawText(QRectF(3, 0, width(), m_headerheight), m_dragtext, QTextOption(Qt::AlignVCenter));
    drag->setPixmap(dragpix);

    //设置鼠标相对拖拽图片的中心位置，在拖动过程中保持该相对位置
    QPoint dragpointatitem = QPoint(dragpix.rect().center());
    drag->setHotSpot(dragpointatitem);
    //设置拖拽图片时鼠标图标
    QPixmap dragcursor(":/tableview/resources/skin/tableview/aero_arrow.png");
    drag->setDragCursor(dragcursor, Qt::MoveAction);

    //进入drag的拖拽消息循环，会依次触发dragEnterEvent、dragMoveEvent、dropEvent消息
    if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
    {
    }
}

//拖动事件
void dragheaderview::dragEnterEvent (QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("gradheaderitem"))
    {
        //接受在这个窗口部件上拖放对象
        event->acceptProposedAction();
    }
    else
    {
        //忽视在这个窗口部件上拖放对象
        event->ignore();
        QHeaderView::dragEnterEvent(event);
    }
}

void dragheaderview::dragLeaveEvent(QDragLeaveEvent *event)
{
    m_toplabel->hide();
    m_bottomlabel->hide();
    m_columnto = -1;
    QHeaderView::dragLeaveEvent(event);
}

void dragheaderview::dragMoveEvent (QDragMoveEvent *event)
{
    if(event->mimeData()->hasFormat("gradheaderitem"))
    {
        //控制滚动条移动
        int dragwidth = m_parent->columnWidth(m_columnfrom);
        int dragleft = event->pos().x() - dragwidth / 2;
        int dragright = event->pos().x() + dragwidth / 2;
        //拖放对象左右两边是否在区域外
        if(dragleft < this->rect().left())
        {
            //qDebug()<< "拖放对象左边边超出区域";
            QScrollBar * horbar = m_parent->horizontalScrollBar();
            int minvalue = horbar->minimum();
            int movevalue = horbar->value() + (dragleft - this->rect().left()) / 2;
            if( minvalue < movevalue)
                horbar->setValue(movevalue);
            else
                horbar->setValue(minvalue);
        }
        if(dragright > this->rect().right())
        {
            //qDebug()<< "拖放对象右边超出区域";
            QScrollBar * horbar = m_parent->horizontalScrollBar();
            int maxvalue = horbar->maximum();
            int movevalue = horbar->value() + (dragright - this->rect().right()) / 2;
            if( maxvalue > movevalue)
                horbar->setValue(movevalue);
            else
                horbar->setValue(maxvalue);
        }
        //控制拖放对象拖放位置
        int currentcolumn = -1;
        QModelIndex index = m_parent->indexAt(event->pos());
        if (index.isValid() && event->pos().y() < 30)
        {
            //qDebug()<< "move "<< index.row() << index.column();
            QRect currentrect = getSectionRect(index.column());
            if(event->pos().x() >= currentrect.width() / 2 + currentrect.left())
            {
                currentcolumn = index.column();
            }
            else
            {
                currentcolumn = index.column() - 1;
            }
        }
        else
        {
            currentcolumn = -1;
        }
        //qDebug() << "currentcolumn " << currentcolumn << "m_columnfrom " << m_columnfrom;
        //在序号列左边、起始列左右两边，则不移动
        if(currentcolumn == -1 || currentcolumn == m_columnfrom || currentcolumn == m_columnfrom - 1)
        {
            m_toplabel->hide();
            m_bottomlabel->hide();
            m_columnto = -1;
        }
        else
        {
            m_columnto = currentcolumn;
            QRect currentrect = getSectionRect(currentcolumn);
            QPoint grect = mapTo(gmainwid, QPoint(currentrect.right() - 5, 0));
            m_toplabel->setGeometry(grect.x(), grect.y() + 30, 10, 10);
            m_toplabel->show();
            m_bottomlabel->setGeometry(grect.x(), grect.y() - 10, 10, 10);
            m_bottomlabel->show();
        }
        event->acceptProposedAction();
        return;
    }
    m_toplabel->hide();
    m_bottomlabel->hide();
    m_columnto = -1;
    event->ignore();
    QHeaderView::dragMoveEvent(event);
}

//放下事件
void dragheaderview::dropEvent (QDropEvent *event)
{
    if(event->mimeData()->hasFormat("gradheaderitem"))
    {
        if(m_columnto != -1)
        {
            movecolumn();
        }
        m_columnto = -1;
        event->acceptProposedAction();
        return;
    }
    m_columnto = -1;
    event->ignore();
    QHeaderView::dropEvent(event);
}

void dragheaderview::movecolumn()
{
    customtablemodel * tablemodel =  m_parent->getCustomTableModel();
    //改变表头数据
    tablemodel->changeHHeaderData(m_columnfrom, m_columnto);
    //改变表格数据
    tablemodel->changeData(m_columnfrom, m_columnto);
    //改变列宽度
    m_parent->changeColumnWidth(m_columnfrom, m_columnto);
    //改变代理
    m_parent->changeDelegate(m_columnfrom, m_columnto);
    //保存列最新顺序
    m_parent->changeColumnId(m_columnfrom, m_columnto);
    //刷新表格
    tablemodel->refrushModel();
    //设置选中项
    m_parent->setDragSelectedRows();
}

/********************multilineheaderview********************/
multilineheaderview::multilineheaderview(Qt::Orientation orientation, multilinetableview * parent)
    : QHeaderView(orientation, parent)
{
    m_bgcolor = QColor(241, 245, 246);
    m_framecolor = QColor(216, 216, 216);
    m_ischeckall = false;
    m_sortby = 1;
    m_currentcolumn = -1;
    m_bmousepressed = false;
    m_hheaderlist.clear();
    m_uniteitemsmap.clear();
    m_uniteitemslist.clear();
    m_parent = parent;
    m_checkpixmap.load(":/tableview/resources/skin/tableview/checked.bmp");
    m_uncheckpixmap.load(":/tableview/resources/skin/tableview/unchecked.bmp");
    m_sortwaitpixmap.load(":/tableview/resources/skin/tableview/sort_wait_api.bmp");
    m_sortascpixmap.load(":/tableview/resources/skin/tableview/sort_asc_api.bmp");
    m_sortdescpixmap.load(":/tableview/resources/skin/tableview/sort_desc_api.bmp");

    //设置表头背景色
    setStyleSheet(QString("QHeaderView::section{background-image:url(:/tableview/resources/skin/tableview/head_api.bmp);"
                          "background-color:transparent;padding-left: 3px;border: 1px solid rgb(%1,%2,%3);}")
                  .arg(m_bgcolor.red()).arg(m_bgcolor.green()).arg(m_bgcolor.blue()));

    //设置表头高度
    setFixedHeight(60);
    //设置表头字体
    QFont headeritemfont = QFont(u8"微软雅黑", 9, QFont::Normal);
    setFont(headeritemfont);
    //设置充满表宽度
    setStretchLastSection(true);
    //设置点击表头响应
    setSectionsClickable(true);
    setHighlightSections(false); //点击表时不对表头行光亮（获取焦点）
    connect(this, SIGNAL(headerClicked(int)), this, SLOT(headerItemClicked(int)));
}

multilineheaderview::~multilineheaderview(void)
{

}

void multilineheaderview::setHorizontalHeaderList(QStringList horizontalHeaderList)
{
    m_hheaderlist = horizontalHeaderList;
}

void multilineheaderview::setUniteItems(int startcolumn, int columncount, QString strtext)
{
    uniteitem item;
    item.startcolumn = startcolumn;
    item.columncount = columncount;
    item.endcolumn = startcolumn + columncount - 1;
    item.strtext = strtext;
    for(int i = startcolumn; i < startcolumn + columncount; i++)
        m_uniteitemsmap.insert(i, item);
    m_uniteitemslist.append(item);
}

void multilineheaderview::paintEvent(QPaintEvent *event)
{
    QHeaderView::paintEvent(event);
}

void multilineheaderview::mousePressEvent ( QMouseEvent * event )
{
    if (event->button() == Qt::LeftButton)
    {
        QModelIndex index = m_parent->indexAt(event->pos());
        QRect currentrect = getSectionRect(index.column());
        if (index.isValid() && event->pos().x() > currentrect.left() + 5
                && event->pos().x() < currentrect.right() - 5)
        {
            //判断是否点在合并单元格内
            for(int i = 0; i < m_uniteitemslist.count(); i++)
            {
                uniteitem item = m_uniteitemslist.at(i);
                if(getUniteItemsRect(item.startcolumn, item.endcolumn).contains(event->pos()))
                {
                    QHeaderView::mousePressEvent(event);
                    return;
                }
            }
            m_bmousepressed = true;
            m_currentindex = index.column();
        }
    }
    QHeaderView::mousePressEvent(event);
}

void multilineheaderview::mouseMoveEvent(QMouseEvent * event)
{
    //判断是否点在合并单元格内
    for(int i = 0; i < m_uniteitemslist.count(); i++)
    {
        uniteitem item = m_uniteitemslist.at(i);
        for(int j = item.startcolumn; j < item.endcolumn; j++)
        {
            int x = sectionViewportPosition(j + 1) - 8;
            QRect rect(x, 0, 16, height() / 2);
            if(rect.contains(event->pos()))
            {
                //setCursor(Qt::ArrowCursor);
                return;
            }
        }
    }
    // 还原鼠标样式
    QApplication::restoreOverrideCursor();
    QHeaderView::mouseMoveEvent(event);
}

void multilineheaderview::mouseReleaseEvent(QMouseEvent * event)
{
    if(event->button() == Qt::LeftButton && m_bmousepressed)
    {
        QModelIndex index = m_parent->indexAt(event->pos());
        if (index.isValid() && index.column() == m_currentindex)
        {
            //判断是否点在合并单元格内
            for(int i = 0; i < m_uniteitemslist.count(); i++)
            {
                uniteitem item = m_uniteitemslist.at(i);
                if(getUniteItemsRect(item.startcolumn, item.endcolumn).contains(event->pos()))
                {
                    QHeaderView::mouseReleaseEvent(event);
                    m_bmousepressed = false;
                    m_currentindex = -1;
                    return;
                }
            }
            emit headerClicked(m_currentindex);
        }
        m_bmousepressed = false;
        m_currentindex = -1;
    }
    QHeaderView::mouseReleaseEvent(event);
}

void multilineheaderview::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();
    if (logicalIndex == 0)
    {
        //绘制表头左边框线
        painter->save();
        QPen pen;
        pen.setColor(m_framecolor);
        pen.setWidth(1);
        pen.setStyle(Qt::SolidLine);
        painter->setPen(pen);
        painter->drawLine(getSectionRect(logicalIndex).topLeft(), getSectionRect(logicalIndex).bottomLeft());
        painter->restore();
        m_ischeckall == true ? drawIcon(painter, logicalIndex, m_checkpixmap) : drawIcon(painter, logicalIndex, m_uncheckpixmap);
    }
    else
    {
        drawItem(painter, logicalIndex);
    }
}


QRect multilineheaderview::getSectionRect(int logicalIndex) const
{
    return QRect(sectionViewportPosition(logicalIndex), 0, sectionSize(logicalIndex), height());
}

QRect multilineheaderview::getIconRect(int logicalIndex) const
{
    QRect sr = getSectionRect(logicalIndex);
    return QRect(sr.left() + 3, sr.center().y() - 6, 14, 14);
}

QRect multilineheaderview::getSortIconRect(int logicalIndex) const
{
    QRect sr = getSectionRect(logicalIndex);
    return QRect(sr.right() - 15, sr.center().y() - 14, 13, 28);
}

QRect multilineheaderview::getUniteRect(int logicalIndex) const
{
    return QRect(sectionViewportPosition(logicalIndex), height() / 2, sectionSize(logicalIndex), height() / 2);
}

QRect multilineheaderview::getSortIconUniteRect(int logicalIndex) const
{
    QRect sr = getUniteRect(logicalIndex);
    return QRect(sr.right() - 15, sr.center().y() - 14, 13, 28);
}

QRect multilineheaderview::getUniteItemsRect(int startcolumn, int endcolumn) const
{
    int x = sectionViewportPosition(startcolumn);
    int y = 0;
    int width = 0;
    for(int i = startcolumn; i <= endcolumn; i++)
    {
        width += sectionSize(i);
    }
    return QRect(x, 0, width, height() / 2);
}

void multilineheaderview::drawIcon(QPainter *painter, int logicalIndex, QPixmap pixmap) const
{
    painter->save();
    QRect brect = getIconRect(logicalIndex);
    painter->drawPixmap(brect, pixmap);
    QFont font = QFont(u8"微软雅黑", 9, QFont::Normal);
    painter->setFont(font);
    QFontMetrics metric(font);
    QString strtext = "序号";
    QRect textrect(getSectionRect(logicalIndex).x() + 23, (getSectionRect(logicalIndex).height() - metric.height()) / 2, metric.width(strtext) + 5, metric.height());
    painter->drawText(textrect, strtext);
    painter->restore();

    //绘制表头单元格右边框线
    painter->save();
    QPen pen;
    pen.setColor(m_framecolor);
    pen.setWidth(1);
    pen.setStyle(Qt::SolidLine);
    painter->setPen(pen);
    painter->drawLine(getSectionRect(logicalIndex).topRight(), getSectionRect(logicalIndex).bottomRight());
    painter->restore();
}

void multilineheaderview::drawItem(QPainter *painter, int logicalIndex) const
{
    QMap<int, uniteitem>::const_iterator columnitem;
    columnitem = m_uniteitemsmap.find(logicalIndex);
    //判断该列是否要合并单元格
    if(columnitem != m_uniteitemsmap.end())
    {
        uniteitem item = columnitem.value();
        if(logicalIndex <= item.endcolumn && logicalIndex >= item.startcolumn)
        {
            //合并单元格绘制
            drawUniteItem(painter, logicalIndex, item);
            return;
        }
    }
    //正常单元格绘制
    //绘制表头单元格内容
    painter->save();
    QFont font = QFont(u8"微软雅黑", 9, QFont::Normal);
    painter->setFont(font);
    QFontMetrics metric(font);
    QString strtext = m_hheaderlist.at(logicalIndex);
    QRect textrect(getSectionRect(logicalIndex).x() + 3, (getSectionRect(logicalIndex).height() - metric.height()) / 2
                   , metric.width(strtext) + 5, metric.height());
    painter->drawText(textrect, strtext);
    painter->restore();

    //绘制表头单元格排序图标
    QRect brect = getSortIconRect(logicalIndex);
    if(logicalIndex == m_currentcolumn)
    {
        switch (m_sortby)
        {
        case 1:
            painter->drawPixmap(brect, m_sortwaitpixmap);
            break;
        case 2:
            painter->drawPixmap(brect, m_sortascpixmap);
            break;
        case 3:
            painter->drawPixmap(brect, m_sortdescpixmap);
            break;
        default:
            break;
        }
    }
    else
    {
        painter->drawPixmap(brect, m_sortwaitpixmap);
    }

    //绘制表头单元格右边框线
    painter->save();
    QPen pen;
    pen.setColor(m_framecolor);
    pen.setWidth(1);
    pen.setStyle(Qt::SolidLine);
    painter->setPen(pen);
    painter->drawLine(getSectionRect(logicalIndex).topRight(), getSectionRect(logicalIndex).bottomRight());
    painter->restore();
}

void multilineheaderview::drawUniteItem(QPainter *painter, int logicalIndex, uniteitem item) const
{
    //绘制表头内容
    painter->save();
    QFont font = QFont(u8"微软雅黑", 9, QFont::Normal);
    painter->setFont(font);
    QFontMetrics metric(font);
    QString strtext = m_hheaderlist.at(logicalIndex);
    QRect textrect(getUniteRect(logicalIndex).x() + 3, (getUniteRect(logicalIndex).height() - metric.height()) / 2
                   + getUniteRect(logicalIndex).top(), metric.width(strtext) + 5, metric.height());
    //绘制表头单元格内容
    painter->drawText(textrect, strtext);
    //绘制表头合并单元格内容
    int unitex = (getUniteItemsRect(item.startcolumn, item.endcolumn).width() - (metric.width(item.strtext) + 5)) / 2
                 + getUniteRect(item.startcolumn).x();
    QRect unitetextrect(unitex, (height() / 2 - metric.height()) / 2
                        , metric.width(item.strtext) + 5, metric.height());
    painter->drawText(unitetextrect, item.strtext);
    painter->restore();

    //绘制表头单元格排序图标
    QRect brect = getSortIconUniteRect(logicalIndex);
    if(logicalIndex == m_currentcolumn)
    {
        switch (m_sortby)
        {
        case 1:
            painter->drawPixmap(brect, m_sortwaitpixmap);
            break;
        case 2:
            painter->drawPixmap(brect, m_sortascpixmap);
            break;
        case 3:
            painter->drawPixmap(brect, m_sortdescpixmap);
            break;
        default:
            break;
        }
    }
    else
    {
        painter->drawPixmap(brect, m_sortwaitpixmap);
    }

    //绘制表头单元格边框线
    painter->save();
    QPen pen;
    pen.setColor(m_framecolor);
    pen.setWidth(1);
    pen.setStyle(Qt::SolidLine);
    painter->setPen(pen);
    //绘制表头单元格右边框线
    painter->drawLine(getUniteRect(logicalIndex).topRight(), getUniteRect(logicalIndex).bottomRight());
    //绘制表头合并单元格右边框线
    painter->drawLine(getSectionRect(item.endcolumn).topRight(), getSectionRect(item.endcolumn).bottomRight());
    //绘制表头合并单元格底边框线
    painter->drawLine(getUniteRect(item.startcolumn).topLeft(), getUniteRect(item.endcolumn).topRight());
    painter->restore();
}

void multilineheaderview::setCheckAll()
{
    emit headerSelectAll();
    isCheckAll(true);
}

void multilineheaderview::setUncheckAll()
{
    emit headerClearSelection();
    isCheckAll(false);
}

void multilineheaderview::isCheckAll(bool ischeckall)
{
    ischeckall == true ? m_ischeckall = true : m_ischeckall = false;
    QRect brect = getIconRect(0);
    update(brect);
}

void multilineheaderview::headerItemClicked(int logicalIndex)
{
    if(logicalIndex == 0)
    {
        m_ischeckall == true ? m_ischeckall = false : m_ischeckall = true;
        m_ischeckall == true ? setCheckAll() : setUncheckAll();
    }
    else
    {
        if(logicalIndex == m_currentcolumn)
        {
            switch (m_sortby)
            {
            case 1:
                m_sortby++;
                break;
            case 2:
                m_sortby++;
                break;
            case 3:
                m_sortby--;
                break;
            default:
                break;
            }
        }
        else
        {
            m_sortby = 3;
            m_currentcolumn = logicalIndex;
        }
        emit headerSortClicked(m_sortby, m_currentcolumn);
    }
}

/********************customtablemodel********************/
customtablemodel::customtablemodel(QObject *parent)
    : QAbstractTableModel(parent), m_modeldataslist(NULL)
{
    m_textcolormap.clear();
}

customtablemodel::~customtablemodel(void)
{
    m_modeldataslist = NULL;
}

void customtablemodel::setHorizontalHeaderList(QStringList horizontalHeaderList)
{
    m_hheaderlist = horizontalHeaderList;
}

void customtablemodel::setVerticalHeaderList(QStringList verticalHeaderList)
{
    m_vheaderlist = verticalHeaderList;
}

int customtablemodel::rowCount(const QModelIndex &parent) const
{
    if(m_vheaderlist.size() > 0)
        return m_vheaderlist.size();

    if(NULL == m_modeldataslist)
        return 0;
    else
        return m_modeldataslist->size();
}

int customtablemodel::columnCount(const QModelIndex &parent) const
{
    if(m_hheaderlist.size() > 0)
        return m_hheaderlist.size();

    if(NULL == m_modeldataslist)
        return 0;
    else if(m_modeldataslist->size() < 1)
        return 0;
    else
        return m_modeldataslist->at(0).size();
}

QVariant customtablemodel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if(NULL == m_modeldataslist)
        return QVariant();

    if(m_modeldataslist->size() < 1)
        return QVariant();

    if(index.row() >= m_modeldataslist->size())
        return QVariant();

    if(index.column() >= m_modeldataslist->at(0).size())
        return QVariant();

    if (role == Qt::TextAlignmentRole)
    {
        return int(Qt::AlignLeft | Qt::AlignVCenter);
    }
    else if (role == Qt::DisplayRole)
    {
        return m_modeldataslist->at(index.row()).at(index.column());
    }
    else if(role == Qt::ForegroundRole)
    {
        QString str_item = m_modeldataslist->at(index.row()).at(index.column());
        QMap<QString, QColor>::const_iterator mapitem;
        mapitem = m_textcolormap.find(str_item);
        if(mapitem != m_textcolormap.end())
            return QVariant(mapitem.value());
        else
            return QVariant();
    }
    return QVariant();
}

bool customtablemodel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    int row = index.row();
    int cloumn = index.column();
    QString str_data = value.toString();
    QStringList templist = m_modeldataslist->at(row);
    templist.replace(cloumn, str_data);
    m_modeldataslist->replace(row, templist);
    return true;
}

QVariant customtablemodel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role == Qt::DisplayRole)
    {
        if(orientation == Qt::Horizontal) // 水平表头
        {
            if(m_hheaderlist.size() > section && section != 0)//水平表头第一列列名隐藏，customheaderview里自绘列名
                return m_hheaderlist[section];
            else
                return QVariant();
        }
        else
        {
            if(m_vheaderlist.size() > section)
                return m_vheaderlist[section]; // 垂直表头
            else
                return QVariant();
        }
    }
    else if (role == Qt::TextAlignmentRole)
    {
        return int(Qt::AlignLeft | Qt::AlignVCenter);
    }
    return QVariant();
}

void customtablemodel::setModalDatas(QList< QStringList > *rowlist)
{
    m_modeldataslist = rowlist;
}

void customtablemodel::refrushModel()
{
    beginResetModel();
    endResetModel();
}

void customtablemodel::changeHHeaderData(int frontcolumn, int tocolumn)
{
    QString strfront = m_hheaderlist.at(frontcolumn);
    m_hheaderlist.removeAt(frontcolumn);
    if(frontcolumn < tocolumn)
        m_hheaderlist.insert(tocolumn, strfront);
    else
        m_hheaderlist.insert(tocolumn + 1, strfront);
}

void customtablemodel::changeData(int frontcolumn, int tocolumn)
{
    for(int i = 0; i < rowCount(); i++)
    {
        QStringList templist = m_modeldataslist->at(i);
        QString strfront = templist.at(frontcolumn);
        templist.removeAt(frontcolumn);
        if(frontcolumn < tocolumn)
            templist.insert(tocolumn, strfront);
        else
            templist.insert(tocolumn + 1, strfront);
        m_modeldataslist->replace(i, templist);
    }
}

/********************tableview********************/
tableview::tableview(QWidget *parent) : QTableView(parent)
{
    m_selectedbgcolor = QColor(255, 247, 205);
    this->horizontalScrollBar()->setStyleSheet(
        "QScrollBar:horizontal{ background:#F0F0F0; height:10px; padding-left:0px; padding-right:0px;}"
        "QScrollBar::handle:horizontal{border-radius:5px; background:#CFCFCF;}"
        "QScrollBar::handle:horizontal::disabled{ background:#DBDBDB;}"
        "QScrollBar::handle:horizontal:hover{ background:#BBBBBB;}"
        "QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal{ background:none; border:none;}"
        "QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal{ background:none;}");

    this->verticalScrollBar()->setStyleSheet(
        "QScrollBar:vertical{ background:#F0F0F0; width:10px; padding-top:0px; padding-bottom:0px;}"
        "QScrollBar::handle:vertical{ border-radius:5px; background:#CFCFCF;}"
        "QScrollBar::handle:vertical::disabled{ background:#DBDBDB;}"
        "QScrollBar::handle:vertical:hover{ background:#BBBBBB;}"
        "QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical{ background:none; border:none;}"
        "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical{ background:none;}");

    this->setStyleSheet(
        QString("QTableView{border:none;background:white;}"
                "QTableView::item:selected{background:rgb(%1,%2,%3);}")
        .arg(m_selectedbgcolor.red()).arg(m_selectedbgcolor.green()).arg(m_selectedbgcolor.blue()));

    //设置自定义按钮与进度条风格
    qApp->setStyleSheet("QProgressBar#delegatebar{border:1px solid grey;text-align: center;background: white;}"
                        "QProgressBar::chunk#delegatebar{border: none;background: rgb(100, 180, 240);}"
                        "QPushButton#delegatebtn{color:rgb(0, 120, 230);"
                        "text-decoration:underline;background:transparent;}");

    this->verticalHeader()->setVisible(false);
    this->setShowGrid(true);
    this->setSelectionBehavior(QAbstractItemView::SelectRows);
    this->setEditTriggers(QAbstractItemView::NoEditTriggers);
    this->setFocusPolicy(Qt::NoFocus);   //去除选中虚线框
    this->setMouseTracking(true);
    this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);//设置非单元滚动
    this->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);//设置非单元滚动
    this->setFont(QFont(u8"微软雅黑", 8, QFont::Normal));
    this->setMouseTracking(true);

    m_icondelegate = new icondelegate(this);
    this->setItemDelegateForColumn(0, m_icondelegate);

    m_customtablemodel = new customtablemodel(this);
    setModel(m_customtablemodel);
    m_customtablemodel->setModalDatas(&m_griddatalist);
    //自定义选中模型
    QItemSelectionModel *selectionModel = new QItemSelectionModel(m_customtablemodel);
    this->setSelectionModel(selectionModel);
    connect(selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
}

tableview::~tableview(void)
{
    m_griddatalist.clear();
}

void tableview::setIconSelection(QModelIndexList selectedlist)
{
    m_icondelegate->setSelectIndexList(selectedlist);
}

void tableview::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
    QTableView::selectionChanged(selected, deselected);
    QItemSelectionModel *selections = selectionModel();
    m_selectedlist = selections->selectedIndexes();
    m_icondelegate->setSelectIndexList(m_selectedlist);

    QModelIndexList selectrowslist = selections->selectedRows(0);
    int selectrowcount = selectrowslist.count();
    if(selectrowcount == this->model()->rowCount())
    {
        emit isCheckAll(true);
    }
    else
    {
        emit isCheckAll(false);
    }
}

void tableview::setHHeader(QStringList hheader)
{
    m_customtablemodel->setHorizontalHeaderList(hheader);
    m_columnidlist.clear();
    for(int i = 0; i < hheader.count(); i++)
    {
        m_columnidlist.append(i);
    }
}

void tableview::SetItemTextColor(QString itemtext, QColor color)
{
    m_customtablemodel->m_textcolormap.insert(itemtext, color);
}

QModelIndexList tableview::getSelectedList()
{
    QItemSelectionModel *selections = selectionModel();
    return selections->selectedIndexes();
}

customtablemodel *tableview::getCustomTableModel()
{
    return m_customtablemodel;
}

QList<int> tableview::getColumnIdList()
{
    return m_columnidlist;
}

void tableview::changeColumnWidth(int frontcolumn, int tocolumn)
{
    QList<int> widthlist;
    for(int i = 0; i < columnCount(); i++)
    {
        widthlist.append(columnWidth(i));
    }
    int frontwidth = widthlist.at(frontcolumn);
    widthlist.removeAt(frontcolumn);
    if(frontcolumn < tocolumn)
        widthlist.insert(tocolumn, frontwidth);
    else
        widthlist.insert(tocolumn + 1, frontwidth);
    for(int i = 0; i < columnCount(); i++)
    {
        setColumnWidth(i, widthlist.at(i));
    }
}

void tableview::changeDelegate(int frontcolumn, int tocolumn)
{
    QList<QAbstractItemDelegate *> delegatelist;
    for(int i = 0; i < columnCount(); i++)
    {
        delegatelist.append(itemDelegateForColumn(i));
    }
    QAbstractItemDelegate *frontdelegate = delegatelist.at(frontcolumn);
    delegatelist.removeAt(frontcolumn);
    if(frontcolumn < tocolumn)
        delegatelist.insert(tocolumn, frontdelegate);
    else
        delegatelist.insert(tocolumn + 1, frontdelegate);
    for(int i = 0; i < columnCount(); i++)
    {
        this->setItemDelegateForColumn(i, delegatelist.at(i));
    }
}

void tableview::changeColumnId(int frontcolumn, int tocolumn)
{
    //保存最新列顺序
    int frontvalue = m_columnidlist.at(frontcolumn);
    m_columnidlist.removeAt(frontcolumn);
    if(frontcolumn < tocolumn)
        m_columnidlist.insert(tocolumn, frontvalue);
    else
        m_columnidlist.insert(tocolumn + 1, frontvalue);
}

void tableview::setDragSelectedRows()
{
    emit DragSelectedRows();
}

void tableview::addRow(QStringList rowList)
{
    m_griddatalist.append(rowList);
    m_customtablemodel->refrushModel();
}

void tableview::remove()
{
    QModelIndexList model_index_list = this->selectedIndexes();
    int model_count = model_index_list.count();
    if(model_count <= 0)
        return;

    QList<int> list_row;
    for(int i = model_count - 1; i >= 0; i--)
    {
        QModelIndex model_index = model_index_list.at(i);
        int row = model_index.row();
        if(!list_row.contains(row))
            list_row.append(row);
    }

    if(list_row.isEmpty())
        return;

    qSort(list_row);

    for(int i = list_row.count() - 1; i >= 0; i--)
    {
        m_griddatalist.removeAt(list_row.at(i));
    }

    m_customtablemodel->refrushModel();
}

void tableview::clear()
{
    m_griddatalist.clear();
    m_icondelegate->clearSelectIndexList();
    m_customtablemodel->refrushModel();
}

int tableview::rowCount()
{
    return m_customtablemodel->rowCount(QModelIndex());
}

int tableview::columnCount()
{
    return m_customtablemodel->columnCount(QModelIndex());
}

void tableview::mousePressEvent(QMouseEvent *event)
{
    //屏蔽点击QTableView空白区域失去高亮显示
    QModelIndex currentindex = indexAt(event->pos());
    if(currentindex == QModelIndex())
    {
        return;
    }
    QTableView::mousePressEvent(event);
}

void tableview::mouseMoveEvent(QMouseEvent * event)
{
    // 还原鼠标样式
    QApplication::restoreOverrideCursor();
    QTableView::mouseMoveEvent(event);
}

bool tableview::eventFilter(QObject *o, QEvent *e)
{
    if(verticalScrollBar() == o)
    {
        if(e->type() == QEvent::Enter)
        {
            QApplication::restoreOverrideCursor();
        }
    }
    else if(horizontalScrollBar() == o)
    {
        if(e->type() == QEvent::Enter)
        {
            QApplication::restoreOverrideCursor();
        }
    }
    return QObject::eventFilter(o, e);
}

/********************customtableview********************/
customtableview::customtableview(QWidget *parent) : tableview(parent)
{
    m_headerview = new customheaderview(Qt::Horizontal, this);
    setHorizontalHeader(m_headerview);
    connect(m_headerview, SIGNAL(headerSelectAll()), this, SLOT(selectAll()));
    connect(m_headerview, SIGNAL(headerClearSelection()), this, SLOT(clearSelection()));
    connect(m_headerview, SIGNAL(headerSortClicked(int, int)), this, SIGNAL(headerSortClicked(int, int)));
    connect(this, SIGNAL(isCheckAll(bool)), m_headerview, SLOT(isCheckAll(bool)));
}

customtableview::~customtableview(void)
{

}

void customtableview::clear()
{
    m_headerview->isCheckAll(false);
    tableview::clear();
}

/********************frozentableview********************/
frozentableview::frozentableview(QWidget *parent) : customtableview(parent)
{
    m_mouselbtnpressed = false;
    m_mouselbtnindexpressed =  QModelIndex();
    m_mouselbtnindexprevious = QModelIndex();
}
frozentableview::~frozentableview()
{

}

void frozentableview::mousePressEvent(QMouseEvent *e)
{
    customtableview::mousePressEvent(e);
    if(e->button() == Qt::LeftButton)
    {
        //qDebug()<<" pressed: "<<this->pos().x()<<","<<this->pos().y();
        if(QApplication::keyboardModifiers() == Qt::ShiftModifier)
        {
            QModelIndex currentindex = indexAt(QPoint(1, e->pos().y()));
            if (currentindex.row() == m_mouselbtnindexpressed.row())//在当前行内移动
            {
                QItemSelectionModel * selectionmodel = selectionModel();
                selectionmodel->clear();
                QModelIndex currentindextop = this->model()->index(currentindex.row(), 0, QModelIndex());
                QModelIndex indexrightbottom = this->model()->index(currentindex.row(), this->model()->columnCount() - 1, QModelIndex());
                selectionmodel->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
                emit selectionRows(currentindex.row(), currentindex.row());
            }
            else	//往下拖选
            {
                int minnum = currentindex.row() > m_mouselbtnindexpressed.row() ? m_mouselbtnindexpressed.row() : currentindex.row();
                int maxnum = currentindex.row() > m_mouselbtnindexpressed.row() ? currentindex.row() : m_mouselbtnindexpressed.row();
                //qDebug() << "minrow:" << minnum << " maxnum:" << maxnum;
                QItemSelectionModel * selectionmodel = selectionModel();
                selectionmodel->clear();
                QModelIndex currentindextop = this->model()->index(minnum, 0, QModelIndex());
                QModelIndex indexrightbottom = this->model()->index(maxnum, this->model()->columnCount() - 1, QModelIndex());
                selectionmodel->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
                emit selectionRows(minnum, maxnum);
            }
        }
        else
        {
            m_mouselbtnindexpressed = indexAt(QPoint(1, e->pos().y()));
            emit currentRowPressed(m_mouselbtnindexpressed.row());
        }
        m_mouselbtnpressed = true;
    }
}

void frozentableview::mouseMoveEvent(QMouseEvent *e)
{
    // 还原鼠标样式
    QApplication::restoreOverrideCursor();
    customtableview::mouseMoveEvent(e);
    if(m_mouselbtnpressed)
    {
        //鼠标在父表格区间且不再冻结列表区间
        if(!this->rect().contains(e->pos()) && m_parentrect.contains(e->pos()))
        {
            //qDebug()<<" move: "<<e->pos().x()<<","<<e->pos().y();
            QModelIndex currentindex = indexAt(QPoint(1, e->pos().y()));
            if(currentindex == QModelIndex())
            {
                return;
            }

            if(m_mouselbtnindexprevious == QModelIndex())
                m_mouselbtnindexprevious = currentindex;
            else if(m_mouselbtnindexprevious != currentindex)
                m_mouselbtnindexprevious = currentindex;

            if (currentindex.row() == m_mouselbtnindexpressed.row())//在当前行内移动
            {
                QItemSelectionModel * selectionmodel = selectionModel();
                selectionmodel->clear();
                QModelIndex currentindextop = this->model()->index(currentindex.row(), 0, QModelIndex());
                QModelIndex indexrightbottom = this->model()->index(currentindex.row(), this->model()->columnCount() - 1, QModelIndex());
                selectionmodel->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
                emit selectionRows(currentindex.row(), currentindex.row());
            }
            else	//往下拖选
            {
                int minnum = currentindex.row() > m_mouselbtnindexpressed.row() ? m_mouselbtnindexpressed.row() : currentindex.row();
                int maxnum = currentindex.row() > m_mouselbtnindexpressed.row() ? currentindex.row() : m_mouselbtnindexpressed.row();
                QItemSelectionModel * selectionmodel = selectionModel();
                selectionmodel->clear();
                QModelIndex currentindextop = this->model()->index(minnum, 0, QModelIndex());
                QModelIndex indexrightbottom = this->model()->index(maxnum, this->model()->columnCount() - 1, QModelIndex());
                selectionmodel->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
                emit selectionRows(minnum, maxnum);
            }
        }
    }
}

void frozentableview::mouseReleaseEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton)
    {
        m_mouselbtnpressed = false;
    }
    QTableView::mouseReleaseEvent(e);
}

void frozentableview::updateCurrentRowPressed(int currentrow)
{
    m_mouselbtnindexpressed = this->model()->index(currentrow, 0, QModelIndex());
}

void frozentableview::updateSelectionRows(int minrow, int maxrow)
{
    QItemSelectionModel * model = selectionModel();
    model->clear();
    QModelIndex currentindextop = this->model()->index(minrow, 0, QModelIndex());
    QModelIndex indexrightbottom = this->model()->index(maxrow, this->model()->columnCount() - 1, QModelIndex());
    model->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
}

void frozentableview::setParentWidgetRect(QRect parentrect)
{
    m_parentrect = parentrect;
}

/********************freezetableview********************/
freezetableview::freezetableview(QWidget *parent) : customtableview(parent)
{
    m_freezecolumns = 2;
    m_mouselbtnpressed = false;
    setSelectionBehavior(QAbstractItemView::SelectItems);
    setFocusPolicy(Qt::NoFocus);
    verticalHeader()->setVisible(false);
    setHorizontalScrollMode(ScrollPerPixel);//按像素滚动
    setVerticalScrollMode(ScrollPerPixel);
    setStyleSheet("QTableView{border:none;background:white;}"
                  "QTableView::item:selected{background:rgb(255,247,205);}");
    initFrozenTableView();
    connect(horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(updateFrozenSectionWidth(int, int, int)));
    connect(m_frozentableview->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this,
            SLOT(updateSectionWidth(int, int, int)));
    connect(m_frozentableview, SIGNAL(headerSortClicked(int, int)), this, SIGNAL(headerSortClicked(int, int)));
    connect(m_frozentableview, SIGNAL(selectionRows(int, int)), this, SLOT(updateSelectionRows(int, int)));
    connect(this, SIGNAL(selectionRows(int, int)), m_frozentableview, SLOT(updateSelectionRows(int, int)));
    connect(this, SIGNAL(currentRowPressed(int)), m_frozentableview, SLOT(updateCurrentRowPressed(int)));
    connect(m_frozentableview, SIGNAL(currentRowPressed(int)), this, SLOT(updateCurrentRowPressed(int)));
    connect(this, SIGNAL(setWidgetRect(QRect)), m_frozentableview, SLOT(setParentWidgetRect(QRect)));
}

freezetableview::~freezetableview()
{

}

void freezetableview::setFreezeColumns(int count)
{
    m_freezecolumns = count;
    for (int col = m_freezecolumns; col < model()->columnCount(); ++col)
        m_frozentableview->setColumnHidden(col, true);
    for(int col = 0; col < m_freezecolumns; ++col)
        m_frozentableview->setColumnWidth(col, columnWidth(col));
    updateFrozenTableViewGeometry();
}

void freezetableview::setFreezeRowHeight(int row, int height)
{
    this->setRowHeight(row, height);
    m_frozentableview->setRowHeight(row, height);
}

void freezetableview::initFrozenTableView()
{
    m_frozentableview = new frozentableview(this);
    m_frozentableview->setModel(model());
    auto pMode = model();
    m_frozentableview->setFocusPolicy(Qt::NoFocus);
    m_frozentableview->verticalHeader()->hide();
    m_frozentableview->setSelectionBehavior(QAbstractItemView::SelectItems);
    m_frozentableview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏滚动条
    m_frozentableview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏滚动条
    m_frozentableview->setSelectionModel(selectionModel());
    m_frozentableview->setVerticalScrollMode(ScrollPerPixel);
    setVerticalScrollBar(m_frozentableview->verticalScrollBar());
    viewport()->stackUnder(m_frozentableview);
    m_frozentableview->show();
    m_frozentableview->setStyleSheet("QTableView{border:none;background:white;}"
                                     "QTableView::item:selected{background:rgb(255,247,205);}"
                                    );
    updateFrozenTableViewGeometry();
}

void freezetableview::updateCurrentRowPressed(int currentrow)
{
    m_mouselbtnindexpressed = this->model()->index(currentrow, 0, QModelIndex());
}

void freezetableview::updateSelectionRows(int minrow, int maxrow)
{
    QItemSelectionModel * model = selectionModel();
    model->clear();
    QModelIndex currentindextop = this->model()->index(minrow, 0, QModelIndex());
    QModelIndex indexrightbottom = this->model()->index(maxrow, this->model()->columnCount() - 1, QModelIndex());
    model->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
}

void freezetableview::updateFrozenSectionWidth(int logicalIndex, int /* oldSize */, int newSize)
{
    if(logicalIndex < m_freezecolumns)
    {
        m_frozentableview->setColumnWidth(logicalIndex, newSize);
        updateFrozenTableViewGeometry();
    }
}

void freezetableview::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize)
{
    if(logicalIndex < m_freezecolumns)
    {
        setColumnWidth(logicalIndex, newSize);
        updateFrozenTableViewGeometry();
    }
}

void freezetableview::resizeEvent(QResizeEvent * event)
{
    QTableView::resizeEvent(event);
    updateFrozenTableViewGeometry();
    emit setWidgetRect(this->rect());
}

//点击哪个位置滚动条则移动到哪个位置
void freezetableview::scrollTo (const QModelIndex & index, ScrollHint hint)
{
    if (index.column() >= m_freezecolumns) //禁用点击冻结列移动滚动条
        QTableView::scrollTo(index, hint);
}

void freezetableview::updateFrozenTableViewGeometry()
{
    int freezeviewwidth = 0;
    for(int col = 0; col < m_freezecolumns; ++col)
        freezeviewwidth += columnWidth(col);

    for(int row = 0; row < this->model()->rowCount(); ++row)
        m_frozentableview->setRowHeight(row, rowHeight(row));

    for (int col = m_freezecolumns; col < model()->columnCount(); ++col)
        m_frozentableview->setColumnHidden(col, true);

    m_frozentableview->setGeometry(verticalHeader()->width() + frameWidth(),
                                   frameWidth(), freezeviewwidth,
                                   viewport()->height() + horizontalHeader()->height());
}

void freezetableview::mousePressEvent(QMouseEvent *e)
{
    customtableview::mousePressEvent(e);
    if(e->button() == Qt::LeftButton)
    {
        //qDebug()<<" pressed: "<<this->pos().x()<<","<<this->pos().y();
        if(QApplication::keyboardModifiers() == Qt::ShiftModifier)
        {
            QModelIndex currentindex = indexAt(QPoint(1, e->pos().y()));
            if (currentindex.row() == m_mouselbtnindexpressed.row())//在当前行内移动
            {
                QItemSelectionModel * selectionmodel = selectionModel();
                selectionmodel->clear();
                QModelIndex currentindextop = this->model()->index(currentindex.row(), 0, QModelIndex());
                QModelIndex indexrightbottom = this->model()->index(currentindex.row(), this->model()->columnCount() - 1, QModelIndex());
                selectionmodel->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
                emit selectionRows(currentindex.row(), currentindex.row());
            }
            else	//往下拖选
            {
                int minnum = currentindex.row() > m_mouselbtnindexpressed.row() ? m_mouselbtnindexpressed.row() : currentindex.row();
                int maxnum = currentindex.row() > m_mouselbtnindexpressed.row() ? currentindex.row() : m_mouselbtnindexpressed.row();
                QItemSelectionModel * selectionmodel = selectionModel();
                selectionmodel->clear();
                QModelIndex currentindextop = this->model()->index(minnum, 0, QModelIndex());
                QModelIndex indexrightbottom = this->model()->index(maxnum, this->model()->columnCount() - 1, QModelIndex());
                selectionmodel->select(QItemSelection(currentindextop, indexrightbottom), QItemSelectionModel::Select);
                emit selectionRows(minnum, maxnum);
            }
        }
        else
        {
            m_mouselbtnindexpressed = indexAt(QPoint(1, e->pos().y()));
            emit currentRowPressed(m_mouselbtnindexpressed.row());
        }
        m_mouselbtnpressed = true;
    }
}

void freezetableview::mouseMoveEvent(QMouseEvent *e)
{
    if(m_mouselbtnpressed)
    {
    }
    customtableview::mouseMoveEvent(e);
}

void freezetableview::mouseReleaseEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton)
    {
        m_mouselbtnpressed = false;
    }
    QTableView::mouseReleaseEvent(e);
}
/********************以上是封装类，作为基类使用********************/

/********************以下是自定义类，根据需求继承基类使用************/
/********************tasktableview********************/
tasktableview::tasktableview(QWidget *parent) : customtableview(parent)
{
    m_colordelegate = new colordelegate(this);
    this->setItemDelegateForColumn(3, m_colordelegate);
    m_progressdelegate = new pushbuttondelegate(this, "任务进度");
    this->setItemDelegateForColumn(4, m_progressdelegate);
    m_resultdelegate = new pushbuttondelegate(this, "任务结果");
    this->setItemDelegateForColumn(5, m_resultdelegate);
    m_progressbardelegate = new progressbardelegate(this);
    this->setItemDelegateForColumn(6, m_progressbardelegate);
    connect(m_progressdelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));
    connect(m_resultdelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));

}
tasktableview::~tasktableview()
{

}

/********************resulttableview********************/
resulttableview::resulttableview(QWidget *parent) : freezetableview(parent)
{
    m_freezecolumns = 2;//设置冻结列数
    m_colordelegate = new colordelegate(this);
    this->setItemDelegateForColumn(3, m_colordelegate);
    m_websitedelegate = new pushbuttondelegate(this);//第二个参数未设置，则读取Model()里内容显示
    this->setItemDelegateForColumn(5, m_websitedelegate);
    m_markcolordelegate = new colordelegate(this);
    this->setItemDelegateForColumn(8, m_colordelegate);
    connect(m_websitedelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));
}
resulttableview::~resulttableview()
{

}

/********************dragtableview********************/
dragtableview::dragtableview(QWidget *parent) : tableview(parent)
{
    m_headerview = new dragheaderview(Qt::Horizontal, this);
    setHorizontalHeader(m_headerview);
    connect(m_headerview, SIGNAL(headerSelectAll()), this, SLOT(selectAll()));
    connect(m_headerview, SIGNAL(headerClearSelection()), this, SLOT(clearSelection()));
    connect(m_headerview, SIGNAL(headerSortClicked(int, int)), this, SIGNAL(headerSortClicked(int, int)));
    connect(this, SIGNAL(isCheckAll(bool)), m_headerview, SLOT(isCheckAll(bool)));

    m_colordelegate = new colordelegate(this);
    this->setItemDelegateForColumn(3, m_colordelegate);
    m_progressdelegate = new pushbuttondelegate(this);
    this->setItemDelegateForColumn(4, m_progressdelegate);
    m_resultdelegate = new pushbuttondelegate(this);
    this->setItemDelegateForColumn(5, m_resultdelegate);
    m_pixmapdelegate = new pixmapdelegate(this);
    this->setItemDelegateForColumn(6, m_pixmapdelegate);
    connect(m_progressdelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));
    connect(m_resultdelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));

}
dragtableview::~dragtableview()
{

}

void dragtableview::addDragRow(QStringList rowlist)
{
    QStringList templist;
    QList<int> columnidlist = getColumnIdList();
    for(int i = 0; i < columnidlist.count(); i++)
    {
        templist.append(rowlist.at(columnidlist.at(i)));
    }
    m_griddatalist.append(templist);
    m_customtablemodel->refrushModel();
}

void dragtableview::setpixmaptypelist(QList<int> showtypelist)
{
    m_pixmapdelegate->setpixmaptypelist(showtypelist);
}

void dragtableview::clear()
{
    m_headerview->isCheckAll(false);
    tableview::clear();
}

/********************multilinetableview********************/
multilinetableview::multilinetableview(QWidget *parent) : tableview(parent)
{
    m_headerview = new multilineheaderview(Qt::Horizontal, this);
    setHorizontalHeader(m_headerview);
    connect(m_headerview, SIGNAL(headerSelectAll()), this, SLOT(selectAll()));
    connect(m_headerview, SIGNAL(headerClearSelection()), this, SLOT(clearSelection()));
    connect(m_headerview, SIGNAL(headerSortClicked(int, int)), this, SIGNAL(headerSortClicked(int, int)));
    connect(this, SIGNAL(isCheckAll(bool)), m_headerview, SLOT(isCheckAll(bool)));

    m_colordelegate = new colordelegate(this);
    this->setItemDelegateForColumn(3, m_colordelegate);
    m_progressdelegate = new pushbuttondelegate(this);
    this->setItemDelegateForColumn(4, m_progressdelegate);
    m_resultdelegate = new pushbuttondelegate(this);
    this->setItemDelegateForColumn(5, m_resultdelegate);
    m_pixmapdelegate = new pixmapdelegate(this);
    this->setItemDelegateForColumn(6, m_pixmapdelegate);
    connect(m_progressdelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));
    connect(m_resultdelegate, SIGNAL(btnClicked(int, int)), this, SIGNAL(btnClicked(int, int)));

}
multilinetableview::~multilinetableview()
{

}

void multilinetableview::setpixmaptypelist(QList<int> showtypelist)
{
    m_pixmapdelegate->setpixmaptypelist(showtypelist);
}

void multilinetableview::clear()
{
    tableview::clear();
    m_headerview->isCheckAll(false);
}

void multilinetableview::setHMultilineHeader(QStringList hheader)
{
    m_headerview->setHorizontalHeaderList(hheader);
    QStringList templist;
    for(int i = 0; i < hheader.count(); i++)
        templist.append("");
    m_customtablemodel->setHorizontalHeaderList(templist);
}

void multilinetableview::setUniteItems(int startcolumn, int columncount, QString strtext)
{
    m_headerview->setUniteItems(startcolumn, columncount, strtext);
}

